<?php
namespace AuctionCore\Other;
use AuctionCore\System\AuctionException;

class XimuApi
{
    public static $ACCESS_ID;                    // 徙木颁发给机构用户调用接口的身份id
    public static $ACCESS_KEY;                   // 徙木颁发给机构用户调用接口的身份key
    private static $MODEL;
    private static $ACTION_CMD;
    private static $SIGN;                           // 签名结果串
    private static $API_URL = "https://open.ximucredit.com/Services.do";
    private static $SIGN_TYPE = "MD5";                    // 签名方式，默认为MD5，（目前仅支持MD5）
    private static $ERRORS;
    
    /**
     * 接口初始化, 必须执行此方法才可以使用接口.
     */
    public function __construct()
    {
        self::$ACCESS_ID  = C('ACCESS_ID.0');
        self::$ACCESS_KEY = C('ACCESS_KEY.0');
    }

    /**
    * 生成code 
    * @param string $model
    * @param string $action_cmd
    * @param array $queryStr 其他参数
    */
    private static function createCode($model,$action_cmd,$str=array()){
        $str['access_id']   = self::$ACCESS_ID;
        $str['access_key']  = self::$ACCESS_KEY;
        $str['model']       = $model;
        $str['action_cmd']  = $action_cmd;
        $aa = array();
        foreach ($str as $key => $value) {
           if ($value == null || $value == '') {
               unset($str[$key]);
               continue;
           }
           $aa[]=$key.'='.trim($value);
        }
        asort($aa);
        $bb = implode("&", $aa);
        // var_dump(http_build_query($str));
        self::$SIGN = base64_encode(pack('H*',strtoupper(md5($bb))));
    }

    /**
     * 用get的方式访问接口.
     * @param string $model   指定接口模块
     * @param string $action_cmd  业务操作名
     * @param array $queryStr  其他参数
     */
    public static function _get($model, $action_cmd,$queryStr=array())
    {   
        $queryStr['model']       = $model;
        $queryStr['action_cmd']  = $action_cmd;
        $queryStr['access_id']   = self::$ACCESS_ID;
        $queryStr['access_key']  = self::$ACCESS_KEY;
        self::createCode($model,$action_cmd,$queryStr);
        $map = array();
        $map['model']       = $model;
        $map['action_cmd']  = $action_cmd;
        $map['access_id']   = self::$ACCESS_ID;
        $map['access_key']  = self::$ACCESS_KEY;
         foreach ($queryStr as $key => $value) {
            $map[$key]  = $value;
        }
        $map['sign']        = self::$SIGN;
        $map['sign_type']   = self::$SIGN_TYPE;
        $urlstr = http_build_query($map);
        $apiUrl   = rtrim(self::$API_URL, '/').'?'.$urlstr;
        // dump($apiUrl);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //ssl
        curl_setopt($ch, CURLOPT_VERBOSE, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //跳过SSL证书检查
        // curl_setopt($ch, CURLOPT_VERBOSE, 1); //debug模式
        curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false );
        curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2 );
        curl_setopt($ch, CURLOPT_CAINFO, ROOT_DIR .'/clcw/cacert.crt'); //设置为证书的路径
        curl_setopt($ch, CURLOPT_SSLKEY, ROOT_DIR .'/clcw/client.key'); //私钥存放路径
        curl_setopt($ch, CURLOPT_SSLCERT, ROOT_DIR .'/clcw/client.pem');//证书存放路径
        curl_setopt($ch, CURLOPT_SSLCERTPASSWD, file_get_contents(ROOT_DIR .'/clcw/password.txt'));//证书密码
        // curl_setopt($ch, CURLOPT_VERBOSE, true);
        // $verbose = fopen('php://temp', 'w+');
        // curl_setopt($ch, CURLOPT_STDERR, $verbose);
        $res = curl_exec($ch);
        // if (!$res) {
        //     dump(curl_error($ch));
        // }
        curl_close($ch);
        // rewind($verbose);
        // $verboseLog = stream_get_contents($verbose);
        // echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
        // var_dump($res);
        // die();
        return self::packData(json_decode($res,true));
    }

    /**
     * 用post的方式访问接口.
     *
     * @param string $model     指定接口模块
     * @param string $action_cmd  指定接口模块的节点
     * @param array  $data       要发送的数据
     */
    public static function _post($model, $action_cmd, $data)
    {   
        $queryStr = array();
        $queryStr['model'] = $model;
        $queryStr['action_cmd']  = $action_cmd;
        $queryStr['access_id'] = self::$ACCESS_ID;
        $queryStr['access_key']  = self::$ACCESS_KEY;
        foreach ($data as $key => $value) {
            $queryStr[$key]  = $value;
        }
        self::createCode($model,$action_cmd,$queryStr);
        $queryStr['sign']        = self::$SIGN;
        $queryStr['sign_type']   = self::$SIGN_TYPE; 
        
        $queryStr = http_build_query($queryStr);
        $apiUrl   = rtrim(self::$API_URL, '/').'?'.$queryStr;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
        curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false );
        curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2 );
        curl_setopt($ch, CURLOPT_CAINFO, ROOT_DIR .'/clcw/cacert.crt'); //设置为证书的路径
        curl_setopt($ch, CURLOPT_SSLKEY, ROOT_DIR .'/clcw/client.key'); //私钥存放路径
        curl_setopt($ch, CURLOPT_SSLCERT, ROOT_DIR .'/clcw/client.pem');//证书存放路径
        curl_setopt($ch, CURLOPT_SSLCERTPASSWD, file_get_contents(ROOT_DIR .'/clcw/password.txt'));//证书密码
        $res = curl_exec($ch);
        // if (!$res) {
        //     dump(curl_error($ch));
        // }
        curl_close($ch);
         return self::packData(json_decode($res));
    }


    /**
    * 对接口返回的数据进行验证
    *
    * @param array $apiReturnData 由_post|| _get方法返回的数据.
    *
    * @return array
    */
    private static function packData($apiReturnData)
    {
        $status = $apiReturnData['code'];
        if ($status != 200 ) {
            $error_msg = '';
            $error_key = '';
            foreach ($apiReturnData['errors'] as $key => $value) {
                $error_msg .= $apiReturnData['errors'][$key];
                $error_key = $key;
            }
            \Think\Log::record($apiReturnData['msg'] . ' ' . $error_msg);
            echo \AuctionCore\Common\Util::auto_jsonp_or_json($_REQUEST,array('code'=>$error_key,'msg'=>AuctionException::$codes[$error_key],'data'=>$res1));
            exit;
        }
        return $apiReturnData;
    }

}
